/*
 * Copyright (c) 2020-2021. the original authors and DEPSEA.ORG
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.depsea.oss.client.minio;

import io.minio.*;
import io.minio.errors.*;
import org.depsea.oss.client.AbstractOssTemplate;
import org.depsea.oss.exception.OssException;
import org.depsea.oss.model.FileStreamInfo;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Wang Chengwei
 * @since 1.0.0 2021/12/1 17:36
 */
public abstract class AbstractMinioOssTemplate extends AbstractOssTemplate {

    protected final MinioClient minioClient;

    protected AbstractMinioOssTemplate(MinioClient minioClient) {
        this.minioClient = minioClient;
    }

    @Override
    protected void doUpload(long size, String bucketName, String fullPath, String originalFilename, String contentType, InputStream ins)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        Map<String, String> metadata = new HashMap<>(1);
        metadata.put("X-Original-Filename", originalFilename);
        PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                .contentType(contentType)
                .stream(ins, size, -1L)
                .bucket(bucketName)
                .userMetadata(metadata)
                .object(fullPath)
                .build();
        this.minioClient.putObject(putObjectArgs);
    }

    @Override
    protected FileStreamInfo doGetOssObject(String bucketName, String fullPath)
            throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        GetObjectArgs getObjectArgs = GetObjectArgs.builder()
                .bucket(bucketName)
                .object(fullPath)
                .build();
        GetObjectResponse objectResponse = this.minioClient.getObject(getObjectArgs);

        FileStreamInfo streamInfo = new FileStreamInfo();
        streamInfo.setContentType(objectResponse.headers().get("Content-Type"));
        streamInfo.setFullPath(objectResponse.object());
        streamInfo.setOriginalFilename(objectResponse.headers().get("x-amz-meta-x-original-filename"));
        streamInfo.setSize((long) objectResponse.available());
        streamInfo.setFileExtension(StringUtils.getFilenameExtension(objectResponse.object()));
        streamInfo.setFileData(objectResponse.readAllBytes());
        return streamInfo;
    }

    protected void deleteObject(String bucketName, String fullPath) {
        try {
            RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fullPath)
                    .build();
            this.minioClient.removeObject(removeObjectArgs);
        } catch (Exception e) {
            throw new OssException("文件删除失败", e);
        }
    }

}
